//
// Created by pulsarv on 21-1-29.
//
#include <opencv2/opencv.hpp>
#include <rc_system/config.h>
#include <rc_log/slog.hpp>
#include <utility>

namespace rccore {
    namespace common {
        bool Config::generate_config(std::string config_file_path) {
            slog::warn << "Generate Default Config File!" << slog::endl;
            cv::FileStorage fswrite(config_file_path, cv::FileStorage::WRITE);
            fswrite.writeComment("Default Config File", true);

            //    <!--摄像头信息-->
            //    <camera>
            //        <index>1</index>
            //    </camera>
            fswrite << "camera"
                    << "{";
            fswrite.write("camera_index", pconfigInfo->camera_index);
            fswrite.writeComment("<摄像头下标>", true);
            fswrite.write("camera_info", pconfigInfo->camera_info);
            fswrite.writeComment("<摄像头标定数据路径>", true);
            fswrite.write("resize_width", pconfigInfo->resize_width);
            fswrite.writeComment("<图像宽度>", true);
            fswrite.write("resize_height", pconfigInfo->resize_height);
            fswrite.writeComment("<图像高度>", true);
            fswrite.write("camera_detcet_size", pconfigInfo->camera_detcet_size);
            fswrite.writeComment("<识别缩放倍数>", true);
            fswrite.write("camera_fps", pconfigInfo->camera_fps);
            fswrite.writeComment("FPS", true);
            fswrite << "}";

            fswrite << "SystemSettings"
                    << "{";
            fswrite.write("debug_window", pconfigInfo->debug_window);
            fswrite.writeComment("<是否打开可视化窗口>", true);
            fswrite << "}";

            fswrite << "Lidar"
                    << "{";
            fswrite.write("lidar_source_from", pconfigInfo->lidar_device_path);
            fswrite.writeComment("lidar_device_path", true);
            fswrite << "}";
            fswrite.release();
            return true;
        }

        Config::Config(std::string config_file_path) : m_config_file_path(std::move(config_file_path)) {
            pconfigInfo = std::make_shared<data_struct::ConfigInfo>();
        }

        std::string Config::getCameraParamFile() const {
            return pconfigInfo->camera_info;
        }

        bool Config::load_config() {
            cv::FileStorage fsread;
            if (!fsread.open(m_config_file_path, cv::FileStorage::READ)) {
                slog::err << "No such file " << m_config_file_path << " to open" << slog::endl;
                generate_config(m_config_file_path);
                return false;
            }
            slog::info << "===============" << m_config_file_path
                       << "=================" << slog::endl;
            try {
                cv::FileNode camera_node = fsread["camera"];

                pconfigInfo->camera_index = (int) camera_node["camera_index"];
                pconfigInfo->camera_info = (std::string) camera_node["camera_info"];
                pconfigInfo->resize_width = (int) camera_node["resize_width"];
                pconfigInfo->resize_height = (int) camera_node["resize_height"];
                pconfigInfo->camera_detcet_size = (float) camera_node["camera_detcet_size"];
                pconfigInfo->camera_fps = (int) camera_node["camera_fps"];

                slog::info << "Camera index:" << pconfigInfo->camera_index << slog::endl;
                slog::info << "Camera Size:" << pconfigInfo->resize_width
                           << " x " << pconfigInfo->resize_height
                           << slog::endl;
                slog::info << "Detcet Size:" << pconfigInfo->camera_detcet_size << slog::endl;
                slog::info << "Camera FPS:" << pconfigInfo->camera_fps << slog::endl;
                slog::info << "Camera Param:" << pconfigInfo->camera_info << slog::endl;

                cv::FileNode system_node = fsread["SystemSettings"];
                pconfigInfo->debug_window = (bool) (int) system_node["debug_window"];
                slog::info << "Debug Window:" << pconfigInfo->debug_window << slog::endl;

                cv::FileNode lidar_node = fsread["Lidar"];
                pconfigInfo->lidar_device_path = (std::string) lidar_node["lidar_device_path"];
                slog::info << "Lidar Device Path: " << pconfigInfo->lidar_device_path << slog::endl;
            } catch (cv::Exception &e) {
                slog::err << e.what() << slog::endl;
                return false;
            } catch (std::exception &e) {
                slog::err << e.what() << slog::endl;
                return false;
            }

            return true;
        }

        Config::~Config() = default;

        Config::Config() = default;


    } // namespace config
} // namespace follow_down
